#include    "config_fw.h"
#include    "includes_fw.h"
#if defined(USB_FW)||(USB_EN)
#include    "lib_retina.h"
#include    "mmpf_usbvend.h"
#include    "mmpf_usbdescr.h"
#include    "mmpf_usbextrn.h"
#include    "mmpf_usbpccam.h"
#if (SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
#include    "mmpf_usbmtp.h"
#include    "mmpf_usbdps.h"
#endif
#include "mmps_3gprecd.h"
#include "mmpf_usbuac.h"
#include "mmpf_usbuvc.h"
#include "mmpf_msg.h"
#include "mmp_reg_usb.h"

/** @addtogroup MMPF_USB
@{
*/

MMP_USHORT  USBEP0TxCnt;
MMP_USHORT  USBConfigDescLen;
#if SUPPORT_HID_FUNC
MMP_USHORT  USBReportDescLen;
#endif
MMP_UBYTE   USBInPhase;
MMP_UBYTE   USBOutPhase;
MMP_UBYTE   USBDevAddr = 0;
MMP_UBYTE   USBRequestType;
MMP_UBYTE   USBConfig;
MMP_UBYTE   USBInterface;
MMP_UBYTE   USBEndpoint;
MMP_UBYTE   USBAlterSetting;

MMP_USHORT  USBFrameNum;
MMP_UBYTE   USBDevice;


MMP_UBYTE   USBCmd;
MMP_UBYTE   glUsbApplicationMode;
MMP_USHORT  USBConfig1Len;

#if (SUPPORT_PCCAM_FUNC==1)
MMP_UBYTE   PCCamModeEnable;
#endif
#if (SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
MTP_DMA_HANDLE  MTPBufHandle;
MMP_ULONG glMtpResNotYet;
MMP_ULONG glMtpClassResDelay;
#endif

#if (SUPPORT_UVC_FUNC==0)
MMP_ULONG   glUsbMSDCState;
MMP_ULONG   glMSDCRxBufOffset;
MMP_UBYTE   gbMSDCCmdBlkWrapper[MSDC_CBW_SIZE];

MMP_ULONG   glUsbOperationSpeed;
MMP_ULONG   glUsbCurrentConfig;
MMP_ULONG   glUsbCurrentInterface;
MMP_ULONG   glUsbCtlTxCnt;
MMP_ULONG   glUsbCtlRxCnt;
MMP_ULONG   glUsbCtlRxCnt;
MMP_ULONG   glUsbCtlState;
MMP_USHORT  gsUsbDeviceStatus;
MMP_USHORT  gsUsbInterfaceStatus[MAX_INTERFACE_NUM];
MMP_USHORT  gsUsbEp0Status;
MMP_USHORT  gsUsbRxEpStatus[MAX_RX_ENDPOINT_NUM];
MMP_USHORT  gsUsbTxEpStatus[MAX_TX_ENDPOINT_NUM];
MMP_ULONG   glUsbUpdateDeviceAddr;
#endif

MMP_ULONG   glTestModeFeature;
#if PCAM_EN==0
MMP_ULONG   glMSDCReady = 0;    //Ted update
#endif
MMP_UBYTE   TestPacket[53] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,
0xFE,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFC,0x7E,0xBF,0xDF
,0xEF,0xF7,0xFB,0xFD,0x7E};

USB_REQUEST_PAYLOAD UsbRequestPayload;
#if USE_SIMPLIFIED_DESC
extern MMP_UBYTE HS_CONFIG_DESCRIPTOR_DATA2[];
extern MMP_UBYTE HS_CONFIG_DESCRIPTOR_DATA1[];
extern MMP_UBYTE CONFIG_DESCRIPTOR_DATA1[];
//mostly using gpUsbDesc[gbUsbHighSpeed] to access these 2 config
#if SUPPORT_SWITCH_CAMERA
MMP_UBYTE *gpUsbDesc[3] = {CONFIG_DESCRIPTOR_DATA1, HS_CONFIG_DESCRIPTOR_DATA1,HS_CONFIG_DESCRIPTOR_DATA2};
#else
MMP_UBYTE *gpUsbDesc[2] = {CONFIG_DESCRIPTOR_DATA1, HS_CONFIG_DESCRIPTOR_DATA1};
#endif
#else
USB_DESCRIPTOR      UsbDescriptorInfo;
#endif


extern MMP_ULONG USBFirmwareBinSize;
extern MMPS_3GPRECD_VIDEO_FORMAT m_VideoFmt;

#if (SUPPORT_UVC_FUNC==1)
static void UsbUVCTxIntHandler(void) ;

MMP_UBYTE UsbRequestPayload_bmRequestType;
MMP_UBYTE UsbRequestPayload_bRequest;
MMP_USHORT UsbRequestPayload_wValue;
MMP_USHORT UsbRequestPayload_wIndex;
MMP_USHORT UsbRequestPayload_wLength;

MMP_UBYTE  gbUsbHighSpeed;
MMP_UBYTE  USBOutData;

MMP_UBYTE gbEP0NotEnd;

#pragma arm section code = "UVC_HEADER_LIST_AREA", rwdata = "UVC_HEADER_LIST_AREA",  zidata = "UVC_HEADER_LIST_AREA"
UVC_VIDEO_PAYLOAD_HEADER glUVCPayloadheader[UVC_DMA_3K_NUM];
MMP_ULONG _usbDescList = 0;
//#define USB_DESC_START_ADDR ((MMP_ULONG)_usbDescList[0])
#pragma arm section code, rwdata,  zidata

USB_DMA_DESC *pUsbDmaDesc = 0; //current 12 bytes USB HW DMA list starting address

#if (USB_SOF_REG_MODE==0)
volatile MMP_ULONG SOFNUM;
volatile MMP_UBYTE uSOFNUM;
#endif
volatile MMP_UBYTE gbdrawflag;
MMP_UBYTE gbausentflag; 
extern MMP_ULONG glCPUFreq;
extern MMPF_OS_FLAGID   SYS_Flag_Hif;
extern volatile MMP_UBYTE usb_close_Tx_flag;
extern MMP_UBYTE usb_preclose_Tx_flag;
extern MMPF_OS_SEMID  usb_ep_protect_sem;

MMP_UBYTE gbCallByISR = 0 ;

volatile MMP_UBYTE gbUSBSuspendFlag = 0;
#if USB_SUSPEND_TEST
volatile MMP_UBYTE gbUSBSuspendEvent = 0, gbUSBResumeEvent = 0;

extern void usb_wakeup_proc(void);
extern void USB_ResumeProcess(void);
extern void USB_SuspendProcess(void);
#endif

//#endif
#endif

MMP_ULONG glPCCamDmaEnable;


extern  MMP_ULONG   glMSDCRxBufAddr;
extern  MMP_ULONG   glMSDCCmdBufAddr;
#endif //#if (CHIP == D_V1)||(CHIP == PYTHON)||(CHIP == PV2)

extern MMP_UBYTE gbSwitchSensor;

#if USB_UVC_BULK_EP
extern int          LinuxProbeCheck;
#endif

#pragma O0

#if (CHIP == P_V2)||(CHIP == VSN_V2)

void StallTx(u_char endpoint)
{
    MMP_USHORT csr;

    csr = UsbReadTxEpCSR(endpoint);
    csr = csr & TXCSR_RW_MASK;
    UsbWriteTxEpCSR(endpoint, csr | SET_TX_SENDSTALL);

}

//------------------------------------------------------------------------------
//  Function    : UsbWriteTxMaxP
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbWriteTxMaxP(MMP_ULONG endpoint, MMP_ULONG size)
{
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
	
	pUSB_CTL->USB_EP[endpoint].USB_EP_TX_MAXP = size;
}

#if (SUPPORT_UVC_FUNC == 0)
//------------------------------------------------------------------------------
//  Function    : UsbWriteRxMaxP
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbWriteRxMaxP(MMP_ULONG endpoint, MMP_ULONG size)
{
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
	
	pUSB_CTL->USB_EP[endpoint].USB_EP_RX_MAXP = size;
}

//------------------------------------------------------------------------------
//  Function    : UsbReadRxEpCOUNT
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
MMP_USHORT UsbReadRxEpCOUNT(MMP_ULONG endpoint)
{
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
    MMP_USHORT tmp = 0;

	
  //  pUSB_CTL->USB_INDEX_EP_SEL = endpoint;

    tmp = (pUSB_CTL->USB_EP[endpoint].USB_EP_COUNT & 0x1FFF);
	
	
	return tmp;
}
#endif

//------------------------------------------------------------------------------
//  Function    : UsbReadEp0CSR
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
MMP_USHORT UsbReadEp0CSR(void)
{
	AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
	
	return pUSB_CTL->USB_EP[0x0].USB_EP_TX_CSR;
}
//------------------------------------------------------------------------------
//  Function    : UsbReadTxEpCSR
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
MMP_USHORT UsbReadTxEpCSR(MMP_ULONG endpoint)
{
	AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
	
	return pUSB_CTL->USB_EP[endpoint].USB_EP_TX_CSR;
}

//------------------------------------------------------------------------------
//  Function    : UsbWriteTxEpCSR
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbWriteTxEpCSR(MMP_ULONG endpoint, MMP_USHORT csr)
{
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;

    pUSB_CTL->USB_INDEX_EP_SEL = 0;
    pUSB_CTL->USB_EP[endpoint].USB_EP_TX_CSR = csr;	
}
//------------------------------------------------------------------------------
//  Function    : UsbWriteEp0CSR
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbWriteEp0CSR(MMP_USHORT csr)
{
    UsbWriteTxEpCSR(0,csr);
}

#if (SUPPORT_UVC_FUNC == 0)
//------------------------------------------------------------------------------
//  Function    : UsbWriteRxEpCSR
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbWriteRxEpCSR(MMP_ULONG endpoint, MMP_USHORT csr)
{
 	AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
	
	pUSB_CTL->USB_EP[endpoint].USB_EP_RX_CSR = csr;	
}
//------------------------------------------------------------------------------
//  Function    : UsbDmaRxConfig
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbDmaRxConfig(MMP_ULONG endpoint, MMP_ULONG fb_addr, MMP_USHORT pkt_byte, MMP_USHORT last_pkt_byte,
                    MMP_ULONG pkt_sum)
{
  	RTNA_DBG_Str(0, "Call UsbDmaRxConfig....!!!\r\n");
   #if 0
   	AITPS_USB_DMA pUSB_DMA = AITC_BASE_USBDMA;
    // ooxx842 add 0x02
    //pUSB_DMA->USB_DMA_CTL = 0x02;

    pUSB_DMA->USB_DMA_FB_ST_ADDR = fb_addr;

    pUSB_DMA->USB_DMA_PKT_BYTE = pkt_byte;
    pUSB_DMA->USB_DMA_PKT_BYTE_LAST = last_pkt_byte;
    pUSB_DMA->USB_DMA_PKT_SUM = pkt_sum;

    pUSB_DMA->USB_DMA_TAR_AND_VAL = 0xF820FFFF;
    pUSB_DMA->USB_DMA_TAR_OR_VAL = 0x01440000;

    pUSB_DMA->USB_DMA_INT_EN = 0x1;

    if(endpoint == 1) {
        pUSB_DMA->USB_DMA_FIFO_ADDR = 0xA824;
        pUSB_DMA->USB_DMA_CMD_ADDR = 0xA914;

        pUSB_DMA->USB_DMA_CTL = 0x25;
    }
    if(endpoint == 2) {
        pUSB_DMA->USB_DMA_FIFO_ADDR = 0xA828;
        pUSB_DMA->USB_DMA_CMD_ADDR = 0xA924;

        pUSB_DMA->USB_DMA_CTL = 0x45;
    }
   #endif
    }
//------------------------------------------------------------------------------
//  Function    : UsbDmaTxConfig
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbDmaTxConfig(MMP_ULONG endpoint, MMP_ULONG fb_addr, MMP_USHORT pkt_byte, MMP_USHORT last_pkt_byte,
                    MMP_ULONG pkt_sum, MMP_ULONG zero_end)
{
	MMP_UBYTE i = 0x0;

	for(i = 0x0; i < pkt_sum; i++) {
		usb_dma_setlist((pkt_byte+1), fb_addr + i*(pkt_byte + 1),
                           LIST_TXPKTRDY|LIST_INDEX|endpoint);
    }
     
    usb_dma_setlist((last_pkt_byte + 1), fb_addr + i*(pkt_byte + 1),
                             LIST_TXPKTRDY|LIST_LAST|LIST_INDEX|endpoint);
}

//------------------------------------------------------------------------------
//  Function    : UsbISODmaTxConfig
//  Parameter   : None
//  Return Value : None
//  Description :  
//------------------------------------------------------------------------------ 
void UsbISODmaTxConfig(MMP_ULONG endpoint, MMP_ULONG fb_addr, MMP_USHORT pkt_byte, MMP_USHORT last_pkt_byte,
                       MMP_ULONG pkt_sum, MMP_ULONG zero_end)
{
	MMP_UBYTE i = 0x0;

	for(i = 0x0; i < pkt_sum; i++) {
        usb_dma_setlist((pkt_byte+1), fb_addr + i*(pkt_byte + 1), LIST_TXPKTRDY|LIST_INDEX|endpoint);
    }

    usb_dma_setlist((last_pkt_byte + 1), fb_addr + i*(pkt_byte + 1), LIST_TXPKTRDY|LIST_LAST|LIST_INDEX|endpoint);
    usb_dma_en(USB_DMA_DONE, endpoint);
}
#endif

void usb_dma_setlist(MMP_USHORT usSize, MMP_ULONG ulFbAddr, MMP_USHORT usPara)
{
    if(usPara&LIST_LAST)
       pUsbDmaDesc->dwNextDescAddr=0;
    else
       pUsbDmaDesc->dwNextDescAddr= (MMP_ULONG)(pUsbDmaDesc+1);

    pUsbDmaDesc->dwPLDAddr=ulFbAddr;
    pUsbDmaDesc->wPara=usPara;
    pUsbDmaDesc->wPLDSize=usSize-1;

    pUsbDmaDesc++;
}


void usb_dma_en(MMP_UBYTE ubEnableInt, MMP_UBYTE ubEndpoint)
{
	AITPS_USB_DMA pUSB_DMA = AITC_BASE_USBDMA;
	#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR   cpu_sr = 0;
	#endif
	
	OS_ENTER_CRITICAL();
	pUSB_DMA->USB_DMA_FB_ST_ADDR = (MMP_ULONG)_usbDescList;
	
	pUSB_DMA->USB_DMA_TAR_AND_VAL = 0xFF10FFFF;
	pUSB_DMA->USB_DMA_TAR_OR_VAL = 0x00A70000;
	pUSB_DMA->USB_DMA_CMD_ADDR = 0x1100|(ubEndpoint<<4); 
	pUSB_DMA->USB_DMA_INT_EN = ubEnableInt;
    #if USB_UVC_BULK_EP
	pUSB_DMA->USB_CLK_GATED_SEL &= 0x10;
    #endif
	
	pUSB_DMA->USB_DMA_CTL = 0x01;
	pUsbDmaDesc = (USB_DMA_DESC*)_usbDescList;
	//gbUsbDmaRun=1;
    OS_EXIT_CRITICAL(); 
}


//------------------------------------------------------------------------------
//  Function    : UsbDmaStop
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbDmaStop(MMP_UBYTE ep)
{
	#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR   cpu_sr = 0;
	#endif
    AITPS_USB_DMA pUSB_DMA = AITC_BASE_USBDMA;
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
    MMP_USHORT csr;

    IRQ_LOCK(
    pUSB_DMA->USB_DMA_CTL = 0x02;
	)


    if((pUSB_CTL->USB_EP[ep].USB_EP_TX_CSR & 0x2) != 0x0) {
        RTNA_DBG_Str(0, "\r\nC1");
        IRQ_LOCK(
            csr = UsbReadTxEpCSR(ep);
            csr = csr & TXCSR_RW_MASK;
            UsbWriteTxEpCSR(ep, csr | SET_TX_FLUSHFIFO);
        )
    }
   	RTNA_WAIT_US(100);
    if((pUSB_CTL->USB_EP[ep].USB_EP_TX_CSR & 0x2) != 0x0) {
        RTNA_DBG_Str(0, "-C2");
        IRQ_LOCK(
            csr = UsbReadTxEpCSR(ep);
            csr = csr & TXCSR_RW_MASK;
            UsbWriteTxEpCSR(ep, csr | SET_TX_FLUSHFIFO);
        )
    }
   	RTNA_WAIT_US(100);
    if((pUSB_CTL->USB_EP[ep].USB_EP_TX_CSR & 0x2) != 0x0) {
        RTNA_DBG_Str(0, "-C3");
        IRQ_LOCK(
        	csr = UsbReadTxEpCSR(ep);
            csr = csr & TXCSR_RW_MASK;
    UsbWriteTxEpCSR(ep, csr | SET_TX_FLUSHFIFO);
        )
    }
   	RTNA_WAIT_US(100);
	if((pUSB_CTL->USB_EP[ep].USB_EP_TX_CSR & 0x2) != 0x0) {
		RTNA_DBG_Str(0, "-C4");
		IRQ_LOCK(
    		csr = UsbReadTxEpCSR(ep);
    	    csr = csr & TXCSR_RW_MASK;
    	    UsbWriteTxEpCSR(ep, csr | SET_TX_FLUSHFIFO);
	    )
	}
   	RTNA_WAIT_US(100);

    IRQ_LOCK(
        pUSB_DMA->USB_DMA_INT_EN = 0;
        pUSB_DMA->USB_DMA_CTL = 0x00;
        pUSB_DMA->USB_DMA_FB_ST_ADDR = 0;
        //pUSB_DMA->USB_DMA_DESC_CNT_NUM = 0;
        pUSB_DMA->USB_DMA_DESC_CNT = 0;
    )
}

extern MMP_USHORT  UVCTxFIFOSize;
//------------------------------------------------------------------------------
//  Function    : UsbDmaTxConfigUVCPayload
//  Parameter   : endpoint      : The endpoint which is used for transfer data
//                payload_addr  : The buffer of tranfer data
//                payload_size  : The data size for transfer
//                                if header_addr!=NULL, it include uvc payload header size)
//                                The max data_size cannot exceed UVCTxFIFOSize*UVC_DMA_PAYLOAD_NUM 
//                max_payload_size: The maximum size of payload.
//                payload_sum   : The number of payloads. Cannot bigger than UVC_DMA_3K_NUM
//                header_addr   : The uvc payload header address.
//                                if header_addr==NULL, 
//                                   uvc payload header is not transfered and controlled in this API
//                                if header_addr!=NULL, 
//                                   uvc payload header will be transfered and controlled in this API
//  Return Value : None
//  Description :  
//                This function will split the data to proper size which folllw UVC spec
//                It is designed for ISO mode.
//------------------------------------------------------------------------------ 
// ISO :  one payload 3K
// BULK : one payload 16K
#if (STREAM_DMA_BLK_VER == 3)
void UsbDmaTxConfigUVCPayload(MMP_ULONG endpoint, MMP_ULONG payload_addr, MMP_ULONG payload_size,
                    MMP_ULONG max_packet_size, MMP_ULONG header_addr, MMP_BOOL dma_en)
{
    MMP_ULONG   transfer_addr, packet_count;
    MMP_ULONG   tx_packet_size, left_size, residue;
    MMP_USHORT  para = 0;
    MMP_UBYTE   idx;
    
    left_size = payload_size + sizeof(UVC_VIDEO_PAYLOAD_HEADER);
    packet_count= left_size / max_packet_size;
    residue= left_size % max_packet_size;
    if(residue)
        packet_count++;

    transfer_addr = payload_addr;
    
    //For ISO mode, packet_count will always be 1
    for(idx=0;idx<packet_count;idx++)
    {
        if(max_packet_size >= left_size ) {
            tx_packet_size = left_size;
            para = LIST_TXPKTRDY|LIST_INDEX|endpoint;//add txpkrdy at the last packet of payload
            if(dma_en)
            {
                para |= LIST_LAST;//add last at the last packet of payload of AIT one time transfer
            }
        } else {
            tx_packet_size = max_packet_size;
            para = LIST_INDEX|endpoint;
            #if USB_UVC_BULK_EP
            para |= LIST_TXPKTRDY;
            #endif
        }

        if(idx==0)//transfer uvc payload header 12B
        {
            tx_packet_size -= sizeof(UVC_VIDEO_PAYLOAD_HEADER);
            left_size -= sizeof(UVC_VIDEO_PAYLOAD_HEADER);
            if(left_size==0)
                usb_dma_setlist(sizeof(UVC_VIDEO_PAYLOAD_HEADER), header_addr, LIST_TXPKTRDY|LIST_INDEX|LIST_LAST|endpoint);
            else
                usb_dma_setlist(sizeof(UVC_VIDEO_PAYLOAD_HEADER), header_addr, LIST_INDEX|endpoint);            
        }
        
        if(tx_packet_size){
            usb_dma_setlist(tx_packet_size, transfer_addr, para);
            transfer_addr += tx_packet_size;
            left_size -= tx_packet_size;
        }
    }
    
    
    if(dma_en)
    {
        usb_dma_en(USB_DMA_DONE, endpoint);
    }
}
#elif (STREAM_DMA_BLK_VER == 2)
void UsbDmaTxConfigUVCPayload(MMP_ULONG endpoint, MMP_ULONG payload_addr, MMP_ULONG payload_size,
                    MMP_ULONG max_payload_size, MMP_USHORT payload_sum, MMP_ULONG header_addr)
{
    MMP_ULONG transfer_addr, left_size, sent_size;
    MMP_USHORT para = 0;
    MMP_UBYTE idx;
    
    transfer_addr = payload_addr;
    left_size = payload_size;
    
    #if 1//checking parameter
    if(max_payload_size>UVCTxFIFOSize)
        RTNA_DBG_Str(0, "Error payload size 1.!!!\r\n");

    if(left_size>UVCTxFIFOSize*UVC_DMA_3K_NUM)
        RTNA_DBG_Str(0, "Error payload size 2.!!!\r\n");
    
    if(payload_sum>UVC_DMA_3K_NUM)
        RTNA_DBG_Str(0, "Error payload numbers.!!!\r\n");
    #endif


    for(idx=0;idx<payload_sum;idx++)
    {        
        if(idx==(payload_sum-1)){
            para |= LIST_LAST;
            sent_size = left_size;
        }
        else{
            sent_size = max_payload_size;
        }

            if(header_addr!=NULL)
            {
                usb_dma_setlist(sizeof(UVC_VIDEO_PAYLOAD_HEADER), header_addr,
                                         LIST_INDEX|endpoint);
                                         
                sent_size -= sizeof(UVC_VIDEO_PAYLOAD_HEADER);
                left_size -= sizeof(UVC_VIDEO_PAYLOAD_HEADER);
            }
            usb_dma_setlist(sent_size, transfer_addr,
                                     LIST_TXPKTRDY|LIST_INDEX|endpoint|para);
                                     
            left_size -= sent_size;
            transfer_addr += sent_size;
        }

    if(left_size!=0)
        RTNA_DBG_Str(0, "transfer size error.!!!\r\n");
        
    usb_dma_en(USB_DMA_DONE, endpoint);
}
#endif
#if (SUPPORT_UVC_FUNC==0)

//------------------------------------------------------------------------------
//  Function    : UsbMSDCRxIntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbMSDCRxIntHandler(void)
{
    MMP_USHORT csr,i;
    MMP_UBYTE *rx_buf;
#if USB_DMA_MODE == 0
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
    MMP_SHORT   rx_cnt;
#endif
    csr = UsbReadRxEpCSR(MSDC_RX_EP_ADDR);

    if(csr & RX_SENTSTALL_BIT) {
        csr = csr & RXCSR_RW_MASK;
        UsbWriteRxEpCSR(MSDC_RX_EP_ADDR, csr | CLEAR_RX_SENTSTALL);
        glUsbMSDCState = MSDC_CBW_STATE;
        return;
    }

#if USB_DMA_MODE
    rx_buf = (MMP_UBYTE *) glMSDCCmdBufAddr;
#else
    rx_buf = (MMP_UBYTE *) (glMSDCRxBufAddr + glMSDCRxBufOffset);
#endif
#if USB_DMA_MODE == 0
    rx_cnt = UsbReadRxEpCOUNT(MSDC_RX_EP_ADDR);
    //RTNA_DBG_Short(0,rx_cnt);
    //RTNA_DBG_Str(0,"-cnt\r\n");

    for(i = 0;i < rx_cnt;i++) {
#if(MSDC_RX_EP2 == 1)
        rx_buf[i] = pUSB_CTL->USB_FIFO_EP[0x2].FIFO_B;
#else
        rx_buf[i] = pUSB_CTL->USB_FIFO_EP[0x1].FIFO_B;
#endif        
    }
#endif
    if(glUsbMSDCState == MSDC_CBW_STATE) {
        for(i=0;i<MSDC_CBW_SIZE;i++){
            gbMSDCCmdBlkWrapper[i]=rx_buf[i];
        }

        #if(MSDC_SUPPORT_AIT_SPECIAL_SCSI_CMD)
        if(gbMSDCCmdBlkWrapper[CBW_CBWCB_INDEX] == MSDC_AIT_SCSI_OPCODE)
            MMPF_MSDC_EnableAITSpecialCmdFlag();
        else
        #endif
            MMPF_MSDC_ProcessCmd();
    }
    else if(glUsbMSDCState == MSDC_DATA_TRANSFER_STATE_RX){
        MMPF_MSDC_TransfreStateRXHandle();
    }
}
//------------------------------------------------------------------------------
//  Function    : UsbMSDCTxIntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbMSDCTxIntHandler(void)
{
    MMP_USHORT csr;
    csr = UsbReadTxEpCSR(MSDC_TX_EP_ADDR);

    //RTNA_DBG_Short(0,csr);
    //RTNA_DBG_Str(0,"-csr\r\n");
    if(csr & TX_SENTSTALL_BIT) {
        csr = csr & TXCSR_RW_MASK;
        UsbWriteTxEpCSR(MSDC_TX_EP_ADDR, csr | CLEAR_TX_SENTSTALL);
        glUsbMSDCState = MSDC_CBW_STATE;
        return;
    }

    if(glUsbMSDCState == MSDC_CBW_STATE) {
        MMPF_MSDC_TriggerUsbRX(glMSDCCmdBufAddr,0x1F);      //reveive next CBW
    }
    else if(glUsbMSDCState == MSDC_CSW_STATE) {
        MMPF_MSDC_SendCsw();
        glUsbMSDCState = MSDC_CBW_STATE;
    }
    else if(glUsbMSDCState == MSDC_DATA_TRANSFER_STATE_TX) {
        MMPF_MSDC_TransfreStateTXHandle();
    }
}
//------------------------------------------------------------------------------
//  Function    : UsbProcessClassCmd
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbProcessClassCmd(void)
{
    MMP_UBYTE request;
    MMP_USHORT csr;
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;

    request = UsbRequestPayload.bRequest;

    switch(request) {
    case CLASS_MASS_STORAGE_RESET_CMD:
        //++Wilson@100224
        	if ( (UsbRequestPayload.wValue!=0)||(UsbRequestPayload.wIndex!=0)||(UsbRequestPayload.wLength!=0) ){
        		UsbWriteEp0CSR(SET_EP0_SENDSTALL);
        		glEp0Stall = MMP_TRUE;
        		pUSB_CTL->USB_INT_EVENT_STS &=~(RESET_INT_BIT);
        		return;
        	}
        	else glEp0Stall=MMP_FALSE;
		//--Wilson@100224
        break;
    case CLASS_GET_MAXLUN_CMD:
        glUsbCtlTxCnt = 1;
        glUsbCtlState = USB_CONTROL_TX;
        break;
    case CLASS_CANCEL_REQUEST_CMD:
#if (SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
            MMPF_MTP_CancelRequest();
#endif
        glUsbCtlRxCnt = 6;
        glUsbCtlState = USB_CONTROL_RX;
        //RTNA_DBG_Str(0,"CLASS_CANCEL_REQUEST_CMD\r\n"); //Andy-- for high speed
        break;
    case CLASS_GET_DEVICE_STATUS_CMD:
        glUsbCtlTxCnt = 4;
        glUsbCtlState = USB_CONTROL_TX;
        //RTNA_DBG_Str(0,"CLASS_GET_DEVICE_STATUS_CMD\r\n"); //Andy-- for high speed
        break;
#if (SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
    case CLASS_RESET_DEVICE_CMD:
            MMPF_MTP_ResetDevice();
        //RTNA_DBG_Str(0,"CLASS_RESET_DEVICE_CMD\r\n"); //Andy-- for high speed

        break;
#endif
    default:
        csr = UsbReadEp0CSR();
        UsbWriteEp0CSR(csr | SET_EP0_SENDSTALL);
        //RTNA_DBG_Str(0,"Unsupport Class Request"); //Andy-- for high speed
        break;
    }
}
//------------------------------------------------------------------------------
//  Function    : UsbClaseeCmdNoDataPhase
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbClaseeCmdNoDataPhase(void)
{
    MMP_UBYTE request;

    request = UsbRequestPayload.bRequest;

    switch(request) {
    case CLASS_MASS_STORAGE_RESET_CMD:
        break;
    case CLASS_RESET_DEVICE_CMD:
        break;
    default:
        RTNA_DBG_Str(0, "UsbClaseeCmdNoDataPhase error\r\n");
        break;
    }
}
//------------------------------------------------------------------------------
//  Function    : UsbClassCmdTx
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbClassCmdTx(void)
{
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
    MMP_UBYTE request;
#if (SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
    MMP_USHORT status;
#endif

    request = UsbRequestPayload.bRequest;
    switch(request) {
        case CLASS_GET_MAXLUN_CMD:
        //++Wilson@100224
            if ( (UsbRequestPayload.wIndex !=0)||(UsbRequestPayload.wValue!=0)||(UsbRequestPayload.wLength!=1)){
            	UsbWriteEp0CSR(EP0_SENDSTALL_BIT);
            	glUsbCtlState = USB_CONTROL_IDLE;
            	return;
            	//UsbWriteRxEpCSR(MSDC_RX_EP_ADDR, (UsbReadRxEpCSR(MSDC_RX_EP_ADDR)|RX_SENTSTALL_BIT));
            }
            else {
				glUsbCtlTxCnt -= 1;
                #if defined(UPDATER_FW)
	            pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B = 0x0;
                #else
	            pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B = MSDC_MAX_UNITS - 1;
                #endif
			}
            break;
		//--Wilson@100224
#if(SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
        case CLASS_GET_DEVICE_STATUS_CMD:	
            glUsbCtlTxCnt -= 4;
            status = MMPF_MTP_GetDeviceState();
            pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B = 0x4;
            pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B = 0x0;
            pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B = status;
            pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B = status>>8;
            break;
#endif
        default:
            RTNA_DBG_Str(0,"UsbClassCmdTx error\r\n");
            break;

    }
    if(glUsbCtlTxCnt == 0) {
        UsbWriteEp0CSR(SET_EP0_TXPKTRDY | EP0_DATAEND_BIT);
        glUsbCtlState = USB_CONTROL_IDLE;
    } else {
        UsbWriteEp0CSR(SET_EP0_TXPKTRDY);
    }
}
//------------------------------------------------------------------------------
//  Function    : UsbClassCmdRx
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbClassCmdRx(void)
{
    MMP_UBYTE request;

    request = UsbRequestPayload.bRequest;

    if(glUsbCtlRxCnt != 0) {
        switch(request) {
        case CLASS_CANCEL_REQUEST_CMD:
            glUsbCtlRxCnt -= 6;
            break;
        default:
            RTNA_DBG_Str(0, "Unsupport UsbClassCmdRx");
            break;
        }

        UsbWriteEp0CSR(SET_EP0_SERVICED_RXPKTRDY);
    } else {
        switch(request) {
        case CLASS_CANCEL_REQUEST_CMD:
            break;
        default:
            RTNA_DBG_Str(0, "Unsupport UsbClassCmdRx");
            break;
        }

#if 0
		{
			AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
	        RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
        RTNA_DBG_Str(0,"\r\n");
	        RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
        RTNA_DBG_Str(0,"\r\n");
	        RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
        RTNA_DBG_Str(0,"\r\n");
	        RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
        RTNA_DBG_Str(0,"\r\n");
	        RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
        RTNA_DBG_Str(0,"\r\n");
	        RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
        RTNA_DBG_Str(0,"\r\n");
        }
#endif
        UsbWriteEp0CSR(SET_EP0_SERVICED_RXPKTRDY | EP0_DATAEND_BIT);
        glUsbCtlState = USB_CONTROL_IDLE;
    }
}
//------------------------------------------------------------------------------
//  Function    : UsbCtlNoDataPhaseMode
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbCtlNoDataPhaseMode(void)
{
    MMP_UBYTE type;
    type = UsbRequestPayload.bmRequestType & USB_REQUEST_TYPE_MASK;

    switch(type) {
    case USB_STANDARD_REQUEST:
        UsbStdCmdNoDataPhase();
        break;
    case USB_CLASS_REQUEST:
        UsbClaseeCmdNoDataPhase();
        break;
    case USB_VENDOR_REQUEST:
        UsbVendorCmdNoDataPhase();
        break;
    }
}


//------------------------------------------------------------------------------
//  Function    : UsbCtlProcessRequest
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbCtlProcessRequest(void)
{
    MMP_UBYTE type;
    type = UsbRequestPayload.bmRequestType & USB_REQUEST_TYPE_MASK;

    switch(type) {
    case USB_STANDARD_REQUEST:
        UsbProcessStdCmd();
        break;
    case USB_CLASS_REQUEST:
        UsbProcessClassCmd();
        break;
    case USB_VENDOR_REQUEST:
        UsbProcessVendorCmd();
        break;
    }
}
//------------------------------------------------------------------------------
//  Function    : UsbCtlIdleMode
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbCtlIdleMode(void)
{
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
    MMP_USHORT csr;

    csr = UsbReadEp0CSR();

    if(!(csr & EP0_RXPKTRDY_BIT)) {
        if(glUsbUpdateDeviceAddr == 1) {
            pUSB_CTL->USB_FADDR = UsbRequestPayload.wValue;
            glUsbUpdateDeviceAddr = 0;
            //RTNA_DBG_Byte(0,pUSB_CTL->USB_FADDR);
            //RTNA_DBG_Str(0,"addr\r\n");
        }
        return;
    }
#if 0
 RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
RTNA_DBG_Str(0,"\r\n");
 RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
RTNA_DBG_Str(0,"\r\n");
 RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
RTNA_DBG_Str(0,"\r\n");
 RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
RTNA_DBG_Str(0,"\r\n");
 RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
RTNA_DBG_Str(0,"\r\n");
 RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
RTNA_DBG_Str(0,"\r\n");
 RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
RTNA_DBG_Str(0,"\r\n");
 RTNA_DBG_Byte(0,pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B);
RTNA_DBG_Str(0,"\r\n");
while(1);
#endif

    UsbRequestPayload.bmRequestType = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B;
    UsbRequestPayload.bRequest = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B;
    UsbRequestPayload.wValue = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_W;
    UsbRequestPayload.wIndex = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_W;
    UsbRequestPayload.wLength = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_W;

#if 0
RTNA_DBG_Byte(0,UsbRequestPayload.bmRequestType);
RTNA_DBG_Str(0,"\r\n");
//RTNA_DBG_Byte(0,UsbRequestPayload.bRequest);
//RTNA_DBG_Str(0,"\r\n");
//RTNA_DBG_Short(0,UsbRequestPayload.wValue);
//RTNA_DBG_Str(0,"\r\n");
//RTNA_DBG_Short(0,UsbRequestPayload.wIndex );
//RTNA_DBG_Str(0,"\r\n");
//RTNA_DBG_Short(0,UsbRequestPayload.wLength);
//RTNA_DBG_Str(0,"\r\n");
//while(1);
#endif
    UsbCtlProcessRequest();

    if(glUsbCtlState == USB_CONTROL_IDLE) {
        UsbCtlNoDataPhaseMode();
        if(glTestModeFeature != 0) {
            UsbWriteEp0CSR(SET_EP0_SERVICED_RXPKTRDY);
            UsbWriteEp0CSR(SET_EP0_TXPKTRDY);
        } else {
            UsbWriteEp0CSR(SET_EP0_SERVICED_RXPKTRDY | EP0_DATAEND_BIT);
        }
        return;
    } else if(glUsbCtlState == USB_CONTROL_TX) {
        UsbWriteEp0CSR(SET_EP0_SERVICED_RXPKTRDY);
    }

    return;
}

//------------------------------------------------------------------------------
//  Function    : UsbCtlTxMode
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbCtlTxMode(void)
{
    MMP_UBYTE type;
    type = UsbRequestPayload.bmRequestType & USB_REQUEST_TYPE_MASK;

    switch(type) {
    case USB_STANDARD_REQUEST:
        UsbStdCmdTx();
        break;
    case USB_CLASS_REQUEST:
        UsbClassCmdTx();
        break;
    case USB_VENDOR_REQUEST:
        UsbVendorCmdTx();
        break;
    }
}
//------------------------------------------------------------------------------
//  Function    : UsbCtlRxMode
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbCtlRxMode(void)
{
    MMP_UBYTE type;
    type = UsbRequestPayload.bmRequestType & USB_REQUEST_TYPE_MASK;

    switch(type) {
    case USB_STANDARD_REQUEST:
        UsbStdCmdRx();
        break;
    case USB_CLASS_REQUEST:
        UsbClassCmdRx();
        break;
    case USB_VENDOR_REQUEST:
        UsbVendorCmdRx();
        break;
    }
}
#endif
//------------------------------------------------------------------------------
//  Function    : UsbRestIntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbRestIntHandler(void)
{
    #if (USB_SOF_REG_MODE==0)
	SOFNUM = 0;
    uSOFNUM = 0;
	#endif
    #if USE_COMMON_CLEAR_FUNC
    clear_ep_sequence(1);
    clear_ep_sequence(2);
    clear_ep_sequence(3);
    #else
    clear_ep1_sequence();
    clear_ep2_sequence();
    clear_ep3_sequence();
    #endif

    A810L_InitUSB();

}
#if (SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
//*****************************************************************
// function : mtp_bulk_in
// input    : none
// output   : none
//*****************************************************************
void mtp_bulk_in(int TxByte)
{
    if(glUsbOperationSpeed == USB_HIGH_SPEED) {
        if(TxByte == 0) {
            UsbDmaTxConfig(MTP_TX_EP_ADDR, MTPBufHandle.TxBufAddr, 0x0, 0x0, 0x0, 0x1);
        } else if(TxByte < 0x200) {
            UsbDmaTxConfig(MTP_TX_EP_ADDR, MTPBufHandle.TxBufAddr, 0x0, TxByte - 1, 0, 0x0);
        } else {
            if((TxByte & 0x1FF) != 0) {
                TxByte = TxByte + 0x200;
            }

            UsbDmaTxConfig(MTP_TX_EP_ADDR, MTPBufHandle.TxBufAddr, 0x1FF, (TxByte - 1) & 0x1FF, (TxByte >> 9) - 1, 0x0);
        }
    } else {
        if(TxByte == 0) {
            UsbDmaTxConfig(MTP_TX_EP_ADDR, MTPBufHandle.TxBufAddr, 0x0, 0x0, 0x0, 0x1);
        } else if(TxByte < 0x40) {
            UsbDmaTxConfig(MTP_TX_EP_ADDR, MTPBufHandle.TxBufAddr, 0x0, TxByte - 1, 0, 0x0);
        } else {
            if((TxByte & 0x3F) != 0) {
                TxByte = TxByte + 0x40;
            }
            UsbDmaTxConfig(MTP_TX_EP_ADDR, MTPBufHandle.TxBufAddr, 0x3F, (TxByte - 1) & 0x3F, (TxByte >> 6) - 1, 0x0);
        }
    }
}
//*****************************************************************
// function : mtp_bulk_out
// input    : none
// output   : none
//*****************************************************************
void mtp_bulk_out(int RxByte)
{
    if(glUsbOperationSpeed == USB_HIGH_SPEED) {
        if(RxByte == 0) {
            RxByte = 0x200;
        }
        if((RxByte & 0x1FF) != 0) {
            RxByte = RxByte + 0x200;
        }
        UsbDmaRxConfig(MTP_RX_EP_ADDR, MTPBufHandle.RxBufAddr, 0x1FF, 0x1FF, (RxByte >> 9) - 1);
    } else {
        if(RxByte == 0) {
            RxByte = 0x40;
        }
        if((RxByte & 0x3F) != 0) {
            RxByte = RxByte + 0x40;
        }
        UsbDmaRxConfig(MTP_RX_EP_ADDR, MTPBufHandle.RxBufAddr, 0x3F, 0x3F, (RxByte >> 6) - 1);
    }
}
//*****************************************************************
// function : mtp_interrupt_in
// input    : none
// output   : none
//*****************************************************************
void mtp_interrupt_in(int TxByte)
{
    MMP_USHORT csr;

    csr = UsbReadTxEpCSR(MTP_INT_EP_ADDR);
    csr = csr & TXCSR_RW_MASK;
    UsbWriteTxEpCSR(MTP_INT_EP_ADDR, csr | SET_TX_TXPKTRDY);
}
#endif
#if (SUPPORT_UVC_FUNC==1)
//------------------------------------------------------------------------------
//  Function    : EnableEx
//  Parameter   : None
//  Return Value : None
//  Description : FIFO mode 
//------------------------------------------------------------------------------  
void EnableEx(MMP_UBYTE endpoint)
{
    MMP_USHORT csr;

    csr = UsbReadTxEpCSR(endpoint);
    csr = csr & TXCSR_RW_MASK;
    UsbWriteTxEpCSR(endpoint, csr | SET_TX_TXPKTRDY);
}

//*********************************************************************
// function : usb_error
// input    : none
// output   : none
//*********************************************************************
void usb_error(void)
{
    RTNA_DBG_Str(0, "usb_error\r\n");
    UsbWriteEp0CSR(SET_EP0_SENDSTALL | SET_EP0_SERVICED_RXPKTRDY);
}

#if USE_SIMPLIFIED_REQ == 0
void class_set_current_value(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(SET_CUR_CMD);
    } 
#if SUPPORT_UAC
    else {
        usb_ac_req_proc(SET_CUR_CMD);
    }
#endif
}        
void class_get_current_value(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(GET_CUR_CMD);
    } 
#if SUPPORT_UAC
    else {
        usb_ac_req_proc(GET_CUR_CMD);
    }
#endif
}        
void class_get_min_value(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(GET_MIN_CMD);
    } 
#if SUPPORT_UAC
    else {
        usb_ac_req_proc(GET_MIN_CMD);
    }
#endif
}        
void class_get_max_value(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(GET_MAX_CMD);
    }
#if SUPPORT_UAC     
    else {
        usb_ac_req_proc(GET_MAX_CMD);
    }
#endif    
}        
void class_get_resolution(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(GET_RES_CMD);
    } 
#if SUPPORT_UAC
    else {
        usb_ac_req_proc(GET_RES_CMD);
    }
#endif    
}        
void class_get_length(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(GET_LEN_CMD);
    } 
#if SUPPORT_UAC    
    else {
        usb_ac_req_proc(GET_MEM_CMD);
    }
#endif    
}       
void class_get_info(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(GET_INFO_CMD);
    }
}        
void class_get_default_value(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(GET_DEF_CMD);
    }
}        
void class_set_resolution(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2) {
        usb_vc_req_proc(SET_RES_CMD);
    } else {
#if SUPPORT_UAC
        usb_ac_req_proc(SET_RES_CMD);
#endif
    }
}        
void class_in_set_current_value(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < 2)
        usb_vc_update_automode();
}
void class_in_get_current_value(void)
{
    USBOutPhase = GET_CUR_CMD;
    usb_ep0_null_out();
}
void class_in_get_min_value(void)
{
    USBOutPhase = GET_MIN_CMD;
    usb_ep0_null_out();
}
void class_in_get_max_value(void)
{
    USBOutPhase = GET_MAX_CMD;
    usb_ep0_null_out();
}
void class_in_get_resolution(void)
{
    USBOutPhase = GET_RES_CMD;
    usb_ep0_null_out();
}
void class_in_get_length(void)
{
    USBOutPhase = GET_LEN_CMD;
    usb_ep0_null_out();
}
void class_in_get_info(void)
{
    USBOutPhase = GET_INFO_CMD;
    usb_ep0_null_out();
}
void class_in_get_default_value(void)
{
    USBOutPhase = GET_DEF_CMD;
    usb_ep0_null_out();
}
void class_in_set_resolution(void)
{
    USBOutPhase = SET_RES_CMD;
    usb_ep0_null_out();
}
#endif //#if USE_SIMPLIFIED_REQ == 0

void class_out_set_current_value(void)
{
    if((UsbRequestPayload_wIndex & 0xff) < UAC_CTL_IF_NO)
        usb_vc_out_data();
#if SUPPORT_UAC
    else
        usb_ac_out_data();
#endif
}

#if USE_SIMPLIFIED_REQ == 0
void class_out_get_current_value(void)
{
}
void class_out_get_min_value(void)
{
}
void class_out_get_max_value(void)
{
}
void class_out_get_resolution(void)
{
}
void class_out_get_length(void)
{
}
void class_out_get_info(void)
{
}
void class_out_get_default_value(void)
{
}
void class_out_set_resolution(void)
{
}
#endif //#if USE_SIMPLIFIED_REQ == 0

//*****************************************************************
// function : class_request_setup
// input    : none
// output   : none
//*****************************************************************
void class_request_setup(void)
{
#if USE_SIMPLIFIED_REQ
    if ((UsbRequestPayload_bRequest == SET_CUR_CMD) ||
        ((UsbRequestPayload_bRequest >= GET_CUR_CMD) && (UsbRequestPayload_bRequest <= GET_DEF_CMD)))
    {
        if((UsbRequestPayload_wIndex & 0xff) < UAC_CTL_IF_NO) {
            usb_vc_req_proc(UsbRequestPayload_bRequest);
        } 
    #if SUPPORT_UAC
        else {
            usb_ac_req_proc(UsbRequestPayload_bRequest);
        }
    #endif
#if SUPPORT_HID_FUNC
    } else if(UsbRequestPayload_bRequest == 0x09) {  // Set Report
        UsbWriteEp0CSR(SET_EP0_SENDSTALL | SET_EP0_SERVICED_RXPKTRDY);
    } else if(UsbRequestPayload_bRequest == 0x0A) {  // Set Idle
        UsbWriteEp0CSR(SET_EP0_SENDSTALL | SET_EP0_SERVICED_RXPKTRDY);
#endif
    }
    else {
        usb_error();
    }
#else
    MMP_UBYTE tmp; 
    tmp = UsbRequestPayload_bRequest;
    if(tmp == SET_CUR_CMD) {
        class_set_current_value();
    } else if(tmp == GET_CUR_CMD) {
        class_get_current_value();
    } else if(tmp == GET_MIN_CMD) {
        class_get_min_value();
    } else if(tmp == GET_MAX_CMD) {
        class_get_max_value();
    } else if(tmp == GET_RES_CMD) {
        class_get_resolution();
    } else if(tmp == GET_LEN_CMD) {
        class_get_length();
    } else if(tmp == GET_INFO_CMD) {
        class_get_info();
    } else if(tmp == GET_DEF_CMD) {
        class_get_default_value();
    } else if(tmp == SET_RES_CMD) {
        class_set_resolution();
    } else {
        usb_error();
    }
#endif
}

//*****************************************************************
// function : class_request_in
// input    : none
// output   : none
//*****************************************************************
void class_request_in(void)
{
#if USE_SIMPLIFIED_REQ
    if(USBCmd == SET_CUR_CMD)  { 
        if((UsbRequestPayload_wIndex & 0xff) < 2)
            usb_vc_update_automode();
    }
    else if ((USBCmd >= GET_CUR_CMD) && (USBCmd <= GET_DEF_CMD))
    {
        USBOutPhase = USBCmd;
#if SUPPORT_HID_FUNC
    } else if(USBCmd == 0x09) {  // Set Report
    } else if(USBCmd == 0x0A) {  // Set Idle
#endif
    }
#else
    if(USBCmd == SET_CUR_CMD) {
        class_in_set_current_value();
    } else if(USBCmd == GET_CUR_CMD) {
        class_in_get_current_value();
    } else if(USBCmd == GET_MIN_CMD) {
        class_in_get_min_value();
    } else if(USBCmd == GET_MAX_CMD) {
        class_in_get_max_value();
    } else if(USBCmd == GET_RES_CMD) {
        class_in_get_resolution();
    } else if(USBCmd == GET_LEN_CMD) {
        class_in_get_length();
    } else if(USBCmd == GET_INFO_CMD) {
        class_in_get_info();
    } else if(USBCmd == GET_DEF_CMD) {
        class_in_get_default_value();
    } else if(USBCmd == SET_RES_CMD) {
        class_in_set_resolution();
    }
#endif
    else {
        usb_error();
    }
}

//*****************************************************************
// function : class_request_out
// input    : none
// output   : none
//*****************************************************************
void class_request_out(void)
{
    if(USBCmd == SET_CUR_CMD)  {
        class_out_set_current_value();
    }
#if USE_SIMPLIFIED_REQ
    else if ((USBCmd >= GET_CUR_CMD) && (USBCmd <= GET_DEF_CMD))
    {
#if SUPPORT_HID_FUNC
    } else if(USBCmd == 0x09) {  // Set Report
    } else if(USBCmd == 0x0A) {  // Set Idle
#endif
    }
#else
    else if(USBCmd == GET_CUR_CMD) {
        class_out_get_current_value();
    } else if(USBCmd == GET_MIN_CMD) {
        class_out_get_min_value();
    } else if(USBCmd == GET_MAX_CMD) {
        class_out_get_max_value();
    } else if(USBCmd == GET_RES_CMD) {
        class_out_get_resolution();
    } else if(USBCmd == GET_LEN_CMD) {
        class_out_get_length();
    } else if(USBCmd == GET_INFO_CMD) {
        class_out_get_info();
    } else if(USBCmd == GET_DEF_CMD) {
        class_out_get_default_value();
    }
#endif
    else {
        usb_error();
    }
    //    UsbWriteEp0CSR(SET_EP0_SERVICED_RXPKTRDY);
}



//*********************************************************************
// function : usb_ep0_setup_done
// input    : none
// output   : none
//*********************************************************************
void usb_ep0_setup_done(void)
{
    MMP_UBYTE tmp;
	AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
    UsbRequestPayload_bmRequestType = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B;
    UsbRequestPayload_bRequest = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B;
    UsbRequestPayload_wValue = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B;
    UsbRequestPayload_wValue += pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B << 8;
    UsbRequestPayload_wIndex = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B;
    UsbRequestPayload_wIndex += pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B << 8;
    UsbRequestPayload_wLength = pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B;
    UsbRequestPayload_wLength += pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B << 8;
//#if (USB_SUSPEND_TEST == 0)
/*
    if((USBFirmwareBinSize == 0) && (USBDevAddr != 0)){
	    RTNA_DBG_Byte(0, UsbRequestPayload_bmRequestType);                            
	    RTNA_DBG_Byte(0, UsbRequestPayload_bRequest);                            
	    RTNA_DBG_Short(0, UsbRequestPayload_wValue);                            
	    RTNA_DBG_Short(0, UsbRequestPayload_wIndex);                            
	    RTNA_DBG_Short(0, UsbRequestPayload_wLength);                            
	    RTNA_DBG_Str(0, "--Setup\r\n");
	}
*/
//#endif
    USBCmd = UsbRequestPayload_bmRequestType;
    tmp = USBCmd;
    tmp &= 0x1f;
    USBRequestType = tmp;
    USBCmd &= 0x60;
    if(USBCmd == 0) {
        std_request_setup();
    } else if(USBCmd == 0x20) {
        class_request_setup();
    } else {
        usb_error();
    }
} 

//*********************************************************************
// function : usb_ep0_in_done
// input    : none
// output   : none
//*********************************************************************
void usb_ep0_in_done(void)
{
    MMP_UBYTE tmp;

    USBCmd = USBInPhase;
    USBInPhase = 0;
    if(USBCmd) {
        tmp = USBCmd;
        tmp &= 0xf0;
        if(tmp == STD_CMD || tmp == 0x70) {
            std_request_in();
        } else if(tmp == CLASS_CMD || tmp == 0x20 || tmp == 0x80 || tmp == 0x00) {
            class_request_in();
        } else {
            usb_error();
        }
    } else {
        usb_error();
    }
}

//*********************************************************************
// function : usb_ep0_out_done
// input    : none
// output   : none
//*********************************************************************
void usb_ep0_out_done(void)
{
    MMP_UBYTE tmp;

    USBCmd = USBOutPhase;
    USBOutPhase = 0;
    if(USBCmd) {
        tmp = USBCmd;
        tmp &= 0xf0;
        if(tmp == STD_CMD || tmp == 0x70) {
            std_request_out();
        } else if(tmp == CLASS_CMD || tmp == 0x20 || tmp == 0x80 || tmp == 0x00) {
            class_request_out();
        } else {
            usb_error();
        }
    } else {
        usb_error();
    }
}

#if USE_COMMON_CLEAR_FUNC
void clear_ep_sequence(const u_char ep)
{
    MMP_USHORT csr;

    csr = UsbReadTxEpCSR(ep);

    if((csr & 0x00FF) != 0) {
        UsbWriteTxEpCSR(ep, csr & 0xFF00);
        csr = UsbReadTxEpCSR(ep);
    }

    csr = csr & TXCSR_RW_MASK;
    UsbWriteTxEpCSR(ep, (csr & (~TX_SENDSTALL_BIT)) | SET_TX_CLRDATATOG);
}
#else
//*****************************************************************
// function : clear_ep1_sequence
// input    : none
// output   : none
//*****************************************************************
void clear_ep1_sequence(void)
{
    MMP_USHORT csr;

    csr = UsbReadTxEpCSR(0x01);

    if((csr & 0x00FF) != 0) {
        UsbWriteTxEpCSR(0x01, csr & 0xFF00);      
        csr = UsbReadTxEpCSR(0x01);
    } 

    csr = csr & TXCSR_RW_MASK;
    UsbWriteTxEpCSR(0x01, (csr & (~TX_SENDSTALL_BIT)) | SET_TX_CLRDATATOG);
    
}

//*****************************************************************
// function : clear_ep2_sequence
// input    : none
// output   : none
//*****************************************************************
void clear_ep2_sequence(void)
{
    MMP_USHORT csr;

    csr = UsbReadTxEpCSR(0x02);

    if((csr & 0x00FF) != 0) {
        UsbWriteTxEpCSR(0x02, csr & 0xFF00);      
        csr = UsbReadTxEpCSR(0x02);
    } 

    csr = csr & TXCSR_RW_MASK;
    UsbWriteTxEpCSR(0x02, (csr & (~TX_SENDSTALL_BIT)) | SET_TX_CLRDATATOG);
}

//*****************************************************************
// function : clear_ep3_sequence
// input    : none
// output   : none
//*****************************************************************
void clear_ep3_sequence(void)
{
    MMP_USHORT csr;

    csr = UsbReadTxEpCSR(0x03);

    if((csr & 0x00FF) != 0) {
        UsbWriteTxEpCSR(0x03, csr & 0xFF00);      
        csr = UsbReadTxEpCSR(0x03);
    } 

    csr = csr & TXCSR_RW_MASK;
    UsbWriteTxEpCSR(0x03, (csr & (~TX_SENDSTALL_BIT)) | SET_TX_CLRDATATOG);
}
#endif

//*****************************************************************
// function : usb_ep0_null_in
// input    : none
// output   : none
//*****************************************************************
void usb_ep0_null_in(void)
{
    USBEP0TxCnt = 0;
    if(gbEP0NotEnd) {
        usb_ep0_xbyte_in();
    } else {
        UsbWriteEp0CSR(EP0_DATAEND_BIT | SET_EP0_SERVICED_RXPKTRDY);   // dont need SET_EP0_TXPKTRDY if zero-size data
    }
    //RTNA_DBG_Str(0,"usb_ep0_null_in\r\n");
}

//*****************************************************************
// function : usb_ep0_xbyte_in
// input    : none
// output   : none
//*****************************************************************
void usb_ep0_xbyte_in(void)
{
    //    USBEP0TxAddr = USBEP0TxBufAddr;
    usb_ep0_in();
}

//*****************************************************************
// function : usb_ep0_in
// input    : none
// output   : none
//*****************************************************************
void usb_ep0_in(void)
{
    if(gbEP0NotEnd)
        UsbWriteEp0CSR(SET_EP0_TXPKTRDY);
    else
        UsbWriteEp0CSR(SET_EP0_TXPKTRDY | EP0_DATAEND_BIT);
}



#endif
//------------------------------------------------------------------------------
//  Function    : UsbEp0IntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbEp0IntHandler(void)
{
    MMP_USHORT csr,i;
	AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;

    if(glTestModeFeature != 0) {
        RTNA_DBG_Str(0, "Start Test Mode\r\n");
        switch(glTestModeFeature >> 8) {
        case TEST_J:
            pUSB_CTL->USB_TESTMODE = 0x2;
            break;
        case TEST_K:
            pUSB_CTL->USB_TESTMODE = 0x4;
            break;
        case TEST_SE0_NAK:
            pUSB_CTL->USB_TESTMODE = 0x1;
            break;
        case TEST_PACKET:
            for(i = 0;i < 53;i++) {
                pUSB_CTL->USB_FIFO_EP[0x0].FIFO_B = TestPacket[i];
            }
            pUSB_CTL->USB_TESTMODE = 0x8;
            UsbWriteEp0CSR(SET_EP0_TXPKTRDY);
            break;
        case TEST_FORCE_ENABLE:
            break;
        }
        glTestModeFeature = 0;
        return;
    } else {
  
    }
#if (SUPPORT_UVC_FUNC==1)
    csr = UsbReadEp0CSR();
    if(csr & EP0_SENTSTALL_BIT) {
        UsbWriteEp0CSR(csr & ~EP0_SENTSTALL_BIT);
        if(csr & EP0_SETUPEND_BIT) {
            RTNA_DBG_Str(0, "after stall, clear setupend\r\n");            
            UsbWriteEp0CSR(SET_EP0_SERVICED_SETUPEND);
            #if UART_RXINT_MODE_EN
            {
                extern MMP_UBYTE gbIsBootComplete;
                gbIsBootComplete = 1;
            }
            #endif

        }
    }
    if(USBInPhase) {
        usb_ep0_in_done();                  
        if(USBEP0TxCnt == 0) {
            if(csr & EP0_SETUPEND_BIT) {
                RTNA_DBG_Str(0,"<<<<after inphase, clear setupend>>>>\r\n");                            
                UsbWriteEp0CSR(SET_EP0_SERVICED_SETUPEND);
            }
        }
    }
	if(USBOutData && (csr & EP0_RXPKTRDY_BIT)) 
    {
        usb_ep0_out_done();   
        if(csr & EP0_SETUPEND_BIT) {
            //RTNA_DBG_Str(0, "after outdata, clear setupend\r\n");                                        
            //                UsbWriteEp0CSR(SET_EP0_SERVICED_SETUPEND);// debug only
        }
    } else if(csr & EP0_RXPKTRDY_BIT) {
        usb_ep0_setup_done();
    }                  

    if(USBOutPhase && USBOutData == 0) {
        usb_ep0_out_done();   

        if(csr & EP0_SETUPEND_BIT) {
            RTNA_DBG_Str(0, "outphase\r\n");                                        
            //                UsbWriteEp0CSR(SET_EP0_SERVICED_SETUPEND);// debug only
        }
    }
#else
    csr = UsbReadEp0CSR();
    if(csr & EP0_SENTSTALL_BIT) {
        UsbWriteEp0CSR(CLEAR_EP0_SENTSTALL);
        glUsbCtlState = USB_CONTROL_IDLE;
    }
    if(csr & EP0_SETUPEND_BIT) {
        UsbWriteEp0CSR(SET_EP0_SERVICED_SETUPEND);
        glUsbCtlState = USB_CONTROL_IDLE;
    }
    if(glUsbCtlState == USB_CONTROL_IDLE) {
        //RTNA_DBG_Str(0,"USB_CONTROL_IDLE\r\n");
        UsbCtlIdleMode();
    }
    if(glUsbCtlState == USB_CONTROL_TX) {
        //RTNA_DBG_Str(0,"USB_CONTROL_TX\r\n");
        UsbCtlTxMode();
    }
    if(glUsbCtlState == USB_CONTROL_RX) {
        //RTNA_DBG_Str(0,"USB_CONTROL_RX\r\n");

        UsbCtlRxMode();
    }
#endif        
}
#if (SUPPORT_PCCAM_FUNC==1)
//------------------------------------------------------------------------------
//  Function    : UsbPCCAMTxIntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbPCCAMTxIntHandler(void)
{
    glPCCamDmaEnable = 0;
}
#endif /* (SUPPORT_PCCAM_FUNC==1) */
//------------------------------------------------------------------------------
//  Function    : UsbEp1TxIntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbEp1TxIntHandler(void)
{
#if PCCAM_TX1_EP_ADDR==0x01
    UsbUVCTxIntHandler();
#endif
}
//------------------------------------------------------------------------------
//  Function    : UsbEp1RxIntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbEp1RxIntHandler(void)
{
#if (SUPPORT_UVC_FUNC==1)
#else
    if(glUsbApplicationMode == USB_MSDC_MODE) {
        UsbMSDCRxIntHandler();
    }
#if (SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
    else if(glUsbApplicationMode == USB_MTP_MODE) {
        MMPF_MTP_BulkOutDone();
    }
#endif
    else if(glUsbApplicationMode == USB_PCSYNC_MODE) {
        PCSYNCBulkOutOk();
    }
#endif    
}
//------------------------------------------------------------------------------
//  Function    : UsbEp1TxIntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbEp2TxIntHandler(void)
{
#if PCCAM_TX1_EP_ADDR==0x02
    UsbUVCTxIntHandler();
#endif
}
extern MMP_USHORT MMPF_USBCTL_PostMsg(MMP_ULONG src_id,MMP_ULONG dst_id,MMP_ULONG msg_id,MMP_ULONG msg_sub_id,void *data);
extern void MMPF_USB_ReleaseDMA(void);
extern MMP_UBYTE gbUvcCommitted;
extern MMP_UBYTE gbVideoEncDoneFlag;
static void UsbUVCTxIntHandler(void)
{
#if (SUPPORT_UVC_FUNC==1)
    //extern MMP_ULONG usbframecount;
  
    //RTNA_DBG_Str(3, "@");
    
    if((usb_preclose_Tx_flag == 1) /*&& (usb_check_reframe == 0)*/)
    {
         //RTNA_DBG_Str(3, "-close-\r\n");  
         usb_close_Tx_flag = 1;
    }
    if((usb_close_Tx_flag == 0) && (gbUvcCommitted == 1)) {
        gbdrawflag = 1;
		MMPF_USBCTL_PostMsg(2,TASK_USB_PRIO,USBCTL_MSG_OTHERS,1,(void *)NULL);
    }
    else if(gbVideoEncDoneFlag == 1){
        gbVideoEncDoneFlag = 0;
        gbdrawflag = 1;
		MMPF_USBCTL_PostMsg(2,TASK_USB_PRIO,USBCTL_MSG_OTHERS,2,(void *)NULL);
    }
    else {//error while developing or end of frame.
        //dbg_printf(3, "[ERR]UVCTx: preclose:%d close:%d, committed:%d\r\n", usb_preclose_Tx_flag, usb_close_Tx_flag, gbUvcCommitted);
    }
	
    MMPF_USB_ReleaseDMA(); //sean@2010_10_04
    
#endif    

}
//------------------------------------------------------------------------------
//  Function    : UsbEp3TxIntHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbEp3TxIntHandler(void)
{
#if (SUPPORT_UVC_FUNC==1)
#else
    if(glUsbApplicationMode == USB_MTP_MODE) {
#if (SUPPORT_MTP_FUNC==1)||(SUPPORT_DPS_FUNC==1)
        MMPF_MTP_InterruptInDone();
#endif
    }
#endif    
}

#if PCAM_EN==0
//------------------------------------------------------------------------------
//  Function    : Enable Host inform Ready 
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void MSDC_Enable_ReadyFlag(void)    //Ted update
{
    glMSDCReady = 1;
}
//------------------------------------------------------------------------------
//  Function    : Reset Host inform Ready flag
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void MSDC_Reset_ReadyFlag(void)    //Ted update
{
    glMSDCReady = 0;
}
#endif

//------------------------------------------------------------------------------
//  Function    : UsbDetectModeHandler
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void UsbDetectModeHandler(void) 
{
#if PCAM_EN==0
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
    
	MMPF_Timer_EnableInterrupt(MMPF_TIMER_2, FALSE);

    pUSB_CTL->USB_POWER &= 0xF0;		//disable suspend mode
#if USB_DMA_MODE
	pUSB_CTL->USB_TX_INT_EN &= ~EP0_INT_BIT;	//disable EP0 interrupt
	pUSB_CTL->USB_INT_EVENT_EN &= ~(RESET_INT_BIT|SUSPEND_INT_BIT);	//Remove? disable suspend and reset interrupt
#else
	pUSB_CTL->USB_TX_INT_EN &= ~(EP0_INT_BIT| EP1_TX_INT_BIT);
#endif
	pUSB_CTL->USB_POWER &= USB_SOFT_CON_B;
#endif
}


MMP_USHORT MMPF_SYS_SendMsg(MMP_ULONG src_id,MMP_ULONG dst_id,MMP_ULONG msg_id,MMP_ULONG msg_sub_id,void *data)
{
    MMP_USHORT ret,err ;
    msg_t *msg;

    msg = allocate_msg(src_id);
    if(!msg ){
        return MSG_ERROR_NONE ;
    }
    msg->src_id = src_id ; /*CallerID*/
    msg->dst_id = dst_id ; /*CalledID*/
    msg->msg_id = msg_id ; /*MSG ID*/
    msg->msg_sub_id = msg_sub_id ; /* MSG Sub Id */
    msg->msg_data = data ; /*API parameter*/
    ret = send_msg(msg,&err,src_id);
    /*destroy message*/
    free_msg( (void *)msg, src_id);
    if(ret) {
        return ret ;
    }
    return err;
}

MMP_USHORT MMPF_SYS_PostMsg(MMP_ULONG src_id,MMP_ULONG dst_id,MMP_ULONG msg_id,MMP_ULONG msg_sub_id,void *data)
{
    MMP_USHORT ret=MSG_ERROR_NONE ;
    msg_t *msg;
    msg = allocate_msg(src_id);
    if(!msg ){
        return MSG_ERROR_NONE ;
    }
    msg->src_id = src_id ; /*CallerID*/
    msg->dst_id = dst_id ; /*CalledID*/
    msg->msg_id = msg_id ; /*MSG ID*/
    msg->msg_sub_id = msg_sub_id ; /* MSG Sub Id */
    msg->msg_data = data ; /*API parameter*/
    ret = post_msg(msg, src_id);
    return ret;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_USB_ISR
//  Parameter   : None
//  Return Value : None
//  Description :
//------------------------------------------------------------------------------
void MMPF_USB_ISR(void)
{
    AITPS_USB_CTL pUSB_CTL = AITC_BASE_USBCTL;
#if USB_DMA_MODE
    AITPS_USB_DMA pUSB_DMA = AITC_BASE_USBDMA;
#endif

#if USB_DMA_MODE
    MMP_USHORT  dma_int;
#endif
    MMP_USHORT  tx_int,rx_int;
    MMP_UBYTE   usb_int;

#if USB_DMA_MODE
    dma_int = pUSB_DMA->USB_DMA_INT_STS & pUSB_DMA->USB_DMA_INT_EN;
#endif
    tx_int = pUSB_CTL->USB_TX_INT_STS & pUSB_CTL->USB_TX_INT_EN;
    rx_int = pUSB_CTL->USB_RX_INT_STS & pUSB_CTL->USB_RX_INT_EN;
    usb_int = pUSB_CTL->USB_INT_EVENT_STS & pUSB_CTL->USB_INT_EVENT_EN;

    if(tx_int != 0) {
        if(tx_int & EP0_INT_BIT) {
            //UsbEp0IntHandler(); //Gason remove
			MMPF_SYS_PostMsg(1,TASK_SYS_PRIO,SYS_MSG_USB_EP0_TX_INT,0,(void *)NULL);
        }
        if(tx_int & EP1_TX_INT_BIT) {
            //UsbEp1TxIntHandler();
        }
        if(tx_int & EP2_TX_INT_BIT) {
            //UsbEp2TxIntHandler();
        }
        if(tx_int & EP3_TX_INT_BIT) {
            //UsbEp3TxIntHandler(); Gason remove
			MMPF_SYS_PostMsg(1,TASK_SYS_PRIO,SYS_MSG_USB_EP3_TX_INT,0,(void *)NULL);
        }
    }
    if(rx_int != 0) {
        if(rx_int & EP1_RX_INT_BIT) {
			MMPF_SYS_PostMsg(1,TASK_SYS_PRIO,SYS_MSG_USB_EP1_RX_INT,0,(void *)NULL);
            //UsbEp1RxIntHandler(); //Gason
        }
        if(rx_int & EP2_RX_INT_BIT) {
			MMPF_SYS_PostMsg(1,TASK_SYS_PRIO,SYS_MSG_USB_EP2_RX_INT,0,(void *)NULL);
            //UsbEp1RxIntHandler(); //Gason
        } 
    }
    if(usb_int != 0) {
        if(usb_int & RESET_INT_BIT) {

#if USB_SUSPEND_TEST
            if(gbUSBSuspendFlag == 1){
                RTNA_DBG_Str(0, "-at rst-\r\n");
                gbUSBSuspendFlag = 0;
            }
#endif
            USBDevAddr=0;
            UsbRestIntHandler();

        }
        if(usb_int & SUSPEND_INT_BIT) {
            if(USBDevAddr!=0)
            {
                RTNA_DBG_Str(0, "-USB Suspend-\r\n");
            }
#if USB_SUSPEND_TEST
            if(/*(USBDevAddr != 0) && */(gbUSBSuspendFlag==0) ){
                usb_uvc_suspend();
                gbUSBSuspendEvent = 1;
                MMPF_SYS_PostMsg(1,TASK_SYS_PRIO,SYS_MSG_USB_SUSPEND_INT,0,(void *)NULL);
            }
#endif

        }
        if(usb_int & RESUME_INT_BIT) {

#if  USB_SUSPEND_TEST
            if(gbUSBSuspendFlag == 1){
                RTNA_DBG_Str(0, "-at resume-\r\n");
                gbUSBSuspendFlag = 0;
            }
#endif                    
            RTNA_DBG_Str(0, "-USB Resume-\r\n");
#if USB_UVC_BULK_EP
            LinuxProbeCheck = 0;
#endif
        }
        if(usb_int & SOF_INT_BIT) {
		#if (USB_SOF_REG_MODE==0)
            if(gbUsbHighSpeed == 0) {
                SOFNUM++;
            } else {
                if(uSOFNUM == 8) {
                    uSOFNUM = 0;
                    SOFNUM++;
                } else {
                    uSOFNUM++;
                }
            }
#endif
        }
    }
#if USB_DMA_MODE
	#if USB_DMA_LIST_MODE == 0  //DMA descriptor list 
    if(dma_int != 0) {
        pUSB_DMA->USB_DMA_INT_STS = 0;

        if(pUSB_DMA->USB_DMA_CTL & 0x04) {
   			MMPF_SYS_PostMsg(1,TASK_SYS_PRIO,SYS_MSG_USB_DMA_EP1_RX_INT,0,(void *)NULL);
        } else {
        #if PCCAM_TX1_EP_ADDR==0x02
			MMPF_SYS_PostMsg(1,TASK_SYS_PRIO,SYS_MSG_USB_DMA_EP2_TX_INT,0,(void *)NULL);
        #endif
        #if PCCAM_TX1_EP_ADDR==0x01  
			MMPF_SYS_PostMsg(1,TASK_SYS_PRIO,SYS_MSG_USB_DMA_EP1_TX_INT,0,(void *)NULL);
        #endif  
        }
        //RTNA_DBG_Str(0,"dma\r\n");
    }
    #endif

    #if USB_DMA_LIST_MODE  //DMA descriptor list 
    if(dma_int != 0x0) {
    	pUSB_DMA->USB_DMA_INT_STS &= ~dma_int;

    	if(dma_int & USB_DMA_DONE) {
    	#if PCCAM_TX1_EP_ADDR==0x01  
    	    MMPF_SYS_PostMsg(1, TASK_SYS_PRIO, SYS_MSG_USB_DMA_EP1_TX_INT, 0, (void *)NULL);
    	#endif
    	}
    	if(dma_int & USB_DMA_TXPKTRDY) {

    	}
    }
    #endif

#endif
}
#endif  //#if   defined(USB_FW)||(USB_EN)
//#undef exUSBINT

/// @}
